package com.dk.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dk.mapper.AutoCodePartMapper;
import com.dk.model.AutoCodePart;
import com.dk.model.AutoCodeRule;
import com.dk.mapper.AutoCodeRuleMapper;
import com.dk.service.AutoCodeRuleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dk.strategy.CodeStrategyHandler;
import com.dk.strategy.PartTypeFactory;
import com.dk.vo.AutoCodeRuleVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 编码生成规则表 服务实现类
 * </p>
 *
 * @author wbh
 * @since 2023-03-18
 */
@Service
public class AutoCodeRuleServiceImpl extends ServiceImpl<AutoCodeRuleMapper, AutoCodeRule> implements AutoCodeRuleService {
    @Resource
    private AutoCodeRuleMapper autoCodeRuleMapper;

    @Resource
    private AutoCodePartMapper autoCodePartMapper;

    @Override
    public List<AutoCodeRuleVO> getInfoListByTrim(AutoCodeRuleVO autoCodeRuleVO) {
        //模糊查询 规则名称,规则编码,启用状态查询
        LambdaQueryWrapper<AutoCodeRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(autoCodeRuleVO.getRuleName()), AutoCodeRule::getRuleName, autoCodeRuleVO.getRuleName());//规则名称
        wrapper.like(StringUtils.isNotBlank(autoCodeRuleVO.getRuleCode()), AutoCodeRule::getRuleCode, autoCodeRuleVO.getRuleCode());//规则编码
        wrapper.eq(StringUtils.isNotBlank(autoCodeRuleVO.getEnableFlag()), AutoCodeRule::getEnableFlag, autoCodeRuleVO.getEnableFlag());//启用状态
        List<AutoCodeRuleVO> collect = autoCodeRuleMapper.selectList(wrapper).stream().map(autoCodeRule -> {
            AutoCodeRuleVO vo = new AutoCodeRuleVO();
            BeanUtils.copyProperties(autoCodeRule, vo);
            return vo;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public void insertInfoAutoCodeRule(AutoCodeRuleVO autoCodeRuleVO) {
        AutoCodeRule autoCodeRule = new AutoCodeRule();
        BeanUtils.copyProperties(autoCodeRuleVO, autoCodeRule);
        autoCodeRuleMapper.insert(autoCodeRule);
    }

    @Override
    public AutoCodeRuleVO getInfoAutoCodeRuleById(Integer ruleId) {
        AutoCodeRule autoCodeRule = autoCodeRuleMapper.selectById(ruleId);
        AutoCodeRuleVO vo = new AutoCodeRuleVO();
        BeanUtils.copyProperties(autoCodeRule, vo);
        return vo;
    }

    @Override
    public void updateInfoAutoCodeRuleById(AutoCodeRuleVO autoCodeRuleVO) {
        AutoCodeRule autoCodeRule = new AutoCodeRule();
        BeanUtils.copyProperties(autoCodeRuleVO, autoCodeRule);
        autoCodeRuleMapper.updateById(autoCodeRule);
    }

    @Override
    public void deleteInfoAutoCodeRuleById(Long ruleId) {
        //此时需要取删除两张表
        //先删除规则表
        autoCodeRuleMapper.deleteById(ruleId);
        //再删除编码生成规则组成表
        LambdaQueryWrapper<AutoCodePart> wrapper = new LambdaQueryWrapper();
        wrapper.eq(AutoCodePart::getRuleId, ruleId);
        autoCodePartMapper.delete(wrapper);
    }

    @Override
    public String autoGenerateEncoding(Long ruleId) {
        StringBuffer buffer = new StringBuffer();//生成的编码
        AutoCodeRule autoCodeRule = autoCodeRuleMapper.selectById(ruleId);//根据传过来的ruleId去查询规则表
        if (StringUtils.equals(autoCodeRule.getEnableFlag(), "N")) { //判断是否启用
            return null;
        }
        //在根据ruleId去查询规则组成表
        LambdaQueryWrapper<AutoCodePart> wrapper = new LambdaQueryWrapper();
        wrapper.orderByAsc(AutoCodePart::getPartIndex);//排序显示
        wrapper.eq(AutoCodePart::getRuleId, ruleId);
        List<AutoCodePart> autoCodeParts = autoCodePartMapper.selectList(wrapper);
        //其中有多种规则需要进行循环
        for (AutoCodePart part : autoCodeParts) {
            //判断分段类型,分段类型，INPUTCHAR：输入字符，NOWDATE：当前日期时间，FIXCHAR：固定字符，SERIALNO：流水号'
            String partType = part.getPartType();
            //将分段类型传入,使用设计模式解耦 --> 策略模式(详见interface CodeStrategyHandler)
            CodeStrategyHandler codeStrategyHandler = PartTypeFactory.map.get(partType);
            StringBuffer code = codeStrategyHandler.code(part);//返回的buffer
            buffer.append(code);
        }
        //此时还需要判断长度,是否需要补全等,以及补全方式等
        if (StringUtils.equals(autoCodeRule.getIsPadded(), "Y")) {
            //需要补全
            Integer maxLength = autoCodeRule.getMaxLength();//最大长度
            String paddedMethod = autoCodeRule.getPaddedMethod();//补全方式
            String paddedChar = autoCodeRule.getPaddedChar();//补全字符
            Integer bufferLenth = buffer.length();//当前字符长度
            Integer differenceLength = maxLength - bufferLenth;//相差长度
            if (differenceLength < 0) {
                return null;
            }
            char[] chars = paddedChar.toCharArray();
            StringBuffer s = new StringBuffer();
            for (Integer i = 0; i < differenceLength; i++) {
                //随机取出补全字符的char
                int random = (int) (Math.random() * paddedChar.length());
                s.append(chars[random]);
            }
            if (StringUtils.equals(paddedMethod, "L")) {
                //左补全
                buffer.insert(0, s);
            } else {
                //右补全
                buffer.append(s);
            }
        }
        return buffer.toString();
    }

}
